iT邦幫忙

2024 iThome 鐵人賽

DAY 2
0

今日主題 primevue番外篇-控制浮水印。
https://ithelp.ithome.com.tw/upload/images/20240908/20169148OfarYDUA5r.png

PrimeVue並沒有 浮水印套件,
浮水印利用別的套件呈現,利用primvue元件來控制字體大小和內容等。

這次,難度有點小提升...

Be cheerful and hopeful.
樂觀向上,充滿希望。

使用 Canvas 套件

  1. 使用 Canvas 套件
    • 使用 getContext('2d') 獲取 2D 上下文,進行繪製。
    • 使用上下文的 API 進行繪圖,
    • 如 fillRect、arc、fillText 等。
     let ctx = canvas.getContext("2d")!;
  1. 繪製顏色
 ctx.fillStyle = props.waterColor;
  1. 繪製文字
  ctx.font = "normal 18px Microsoft Yahei";

Props(屬性)- 定義了組件接受的屬性:

  • inputText: 水印顯示的文字。
  • waterWidth: 水印的寬度。
  • waterColor: 水印文字的顏色。
  • waterRotate: 水印文字的旋轉角度。
export default defineComponent({
  props: {
inputText: {
      type: String,
      default: "",
    },
    waterWidth: {
      type: Number,
      default: "",
    },
    waterColor: {
      type: String,
      default: "",
    },
    waterRotate: {
      type: Number,
      default: "",
    },
  },
  setup(props) {
    const maskDiv = ref({} as HTMLDivElement);
    const canvasWidth = ref(Number(props.waterWidth));
    const canvasRef = ref(document.createElement("canvas"));
    const inputText = ref(props.inputText);

初始化浮水印

  • 創建一個 div 元素作為水印容器,並將其添加到 document.body 中。
  • 設置一個 canvas 元素來繪製水印文字。
  • 使用 canvas 的 2D 上下文繪製文字,並旋轉畫布以實現水印效果。
  • 將 canvas 轉換為 PNG 圖像並設置為水印容器的背景圖像。

移除水印函數

移除水印容器,清理 DOM。

const removeMaskDiv = () => {
  if (document.body.contains(maskDiv.value)) {
    document.body.removeChild(maskDiv.value);
  }
};

監視 DOM 變化

使用 MutationObserver 監視 DOM 變化,以便在水印容器被刪除或屬性改變時重新初始化水印。

const callback = (mutations: MutationRecord[]) => {
  if (mutations[0].target.id === "_waterMark") {
    removeMaskDiv();
  }
  if (mutations[0].attributeName === "id") {
    removeMaskDiv();
    init();
  }
  if (
    mutations[0].removedNodes[0] &&
    mutations[0].removedNodes[0].id === "_waterMark"
  ) {
    init();
  }
};

const Monitor = () => {
  let body = document.getElementsByTagName("body")[0];
  let options = {
    childList: true,
    attributes: true,
    characterData: true,
    subtree: true,
    attributeOldValue: true,
    characterDataOldValue: true,
  };
  let observer = new MutationObserver(callback);
  observer.observe(body, options);
};

響應式數據監視

當 inputText、waterColor 或 waterRotate 改變時,重新初始化水印。

watch(
  () => props.inputText,
  () => {
    removeMaskDiv();
    inputText.value = props.inputText;
  }
);

watch(
  () => props.waterColor,
  () => {
    removeMaskDiv();
  }
);

watch(
  () => props.waterRotate,
  () => {
    removeMaskDiv();
  }
);

生命周期

  • onMounted: 組件掛載後初始化水印並開始監視 DOM 變化。
  • onBeforeUnmount: 組件銷毀前移除水印。
onMounted(() => {
  init();
  Monitor();
});

onBeforeUnmount(() => {
  removeMaskDiv();
});

使用浮水印組件

提供一個界面讓用戶輸入水印文字、寬度、顏色和旋轉角度。
這些值會傳遞給 WatermarkComponent,以顯示相應的水印。

<script setup>
import { ref } from "vue";
import WatermarkComponent from "./component.vue";

const text = ref("同學姓名<br>yyyy/mm/dd hh:mm");
text.value = text.value.replace(/<br>/g, "\n");

const width = ref(300);
const color = ref("#4a4a4a");
const rotate = ref(30);
</script>

<template>
  <div>
    <textarea v-model="text"></textarea>
    <input type="number" v-model="width" />
    <input type="text" v-model="color" />
    <input type="number" v-model="rotate" />
  </div>
  <WatermarkComponent
    :inputText="text"
    :waterWidth="width"
    :waterColor="color"
    :waterRotate="rotate"
  />
</template>

<style lang="scss" scoped></style>

參考資料:
https://github.com/StephenOo/vue-canvas-waterMark/blob/master/waterMark.vue


上一篇
Day16- PickList 雙列表
下一篇
Day18- Modal 彈窗視圖
系列文
深入探索PrimeVue 套件及元件寫法29
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言